package com.example.demo.controller;

import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.example.demo.pojo.*;
import com.example.demo.service.OrderChildFormService;
import com.example.demo.service.OrderFormService;
import com.example.demo.service.ShopCartService;
import com.example.demo.service.WarehouseService;
import com.example.demo.util.GetOrderSelId;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import springfox.documentation.spring.web.json.Json;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;



@Controller
@Api(value = "订单生成" , tags = "订单生成并加入数据库")
@RequestMapping("/getOrderForm")
public class OrderFormController {
    @Resource
    private RedisTemplate<String,Object> redisTemplate;
    @Resource(name="orderFormService")
    private OrderFormService orderFormService;
    @Resource(name = "shopCartService")
    private ShopCartService shopCartService;
    @Resource(name = "orderChildFormService")
    private OrderChildFormService orderChildFormService;
    @Autowired
    private WarehouseService warehouseService;
    OrderForm orderForm= new OrderForm();
    OrderChildForm orderChildForm=new OrderChildForm();
    private  String order="";
    @RequestMapping(value = "/getOrderForm", method = RequestMethod.POST)
    @ApiOperation(value = "获取订单编号",notes = "传入参数，生成订单编号，十五分钟后订单失效")
    @ApiImplicitParams({
            @ApiImplicitParam(name="shopcartIds",value = "购物车id,传数组"),
            @ApiImplicitParam(name="addressId",value = "地址ID"),
            @ApiImplicitParam(name="warehouseId",value = "仓库id"),
            })
       private String getOrderFormAll(int[] shopcartIds,int addressId,int warehouseId){
       try{
            String time=String.valueOf(new Date().getTime());
            String qian=String.valueOf((int)(Math.random()*900)+100);
            String hou=String.valueOf((int)(Math.random()*90000)+10000);
            String tonTime=time.substring(3);
             order=qian+tonTime+hou;
            List<Shopcart> getAll;
            double totalPriceSum=0.0;
            double totalPrice=0.0;
            double total=0.0;
            int uid=0;
            int getGoodsid=0;
            int getShopnumber=0;
            List  sum=new ArrayList();
            for (int i=0;i<shopcartIds.length;i++){
                getAll=new ArrayList<>();
                getAll=shopCartService.getShopId(shopcartIds[i]);
                for (Shopcart s:getAll) {
                    CommodityList commodityList;
                    System.out.println(s.getGoodsid());
                    commodityList = shopCartService.getCommId(s.getGoodsid());
                    //总价
                    System.out.println(commodityList.getPrice());
                    totalPrice=commodityList.getPrice()*s.getShopnumber();
                    sum.add(totalPrice);
                    uid=s.getUid();
                }
            }
            for (int g=0;g<sum.size();g++){
                double a=(double)sum.get(g);
                totalPriceSum+=a;
            }
            orderForm.setAddressid(addressId);
            orderForm.setUserid(uid);
            orderForm.setOrderstatusid(1);
            orderForm.setTotalprice(totalPriceSum);
            orderForm.setCancelled(1);
            orderForm.setWarehouseid(warehouseId);
            orderForm.setOrdernumber(order);
            int ff=orderFormService.insertSelective(orderForm);
            for (int i=0;i<shopcartIds.length;i++){
                getAll=new ArrayList<>();
                getAll=shopCartService.getShopId(shopcartIds[i]);
                for (Shopcart s:getAll) {
                    getGoodsid=s.getGoodsid();
                    getShopnumber=s.getShopnumber();
                    CommodityList commodityList;
                    System.out.println(s.getGoodsid());
                    commodityList = shopCartService.getCommId(s.getGoodsid());
                    //总价
                    totalPrice=commodityList.getPrice()*s.getShopnumber();
                    total=totalPrice;
                    orderChildForm.setGoodsid(getGoodsid);
                    orderChildForm.setMoney(total);
                    orderChildForm.setNumber(getShopnumber);
                    orderChildForm.setOrderid(orderForm.getOrderid());
                    int aa = orderChildFormService.insertSelective(orderChildForm);
                }
            }
            redisTemplate.opsForValue().set(order,orderForm);
            redisTemplate.expire(order,30,TimeUnit.MINUTES);
            return JSON.toJSONString(orderForm);
        }catch (Exception e){
            return JSON.toJSONString(orderForm);
       }
    }
    @ApiOperation(value = "支付",notes = "用户点击支付，如果超时返回0(订单失效)")
    @ApiImplicitParams({
            @ApiImplicitParam(name="orderNumber",value = "订单号"),
    })
    @RequestMapping("/money")
    private String money(HttpServletRequest httpRequest, HttpServletResponse httpResponse,String orderNumber) throws IOException, AlipayApiException {
        OrderForm getOrder= orderFormService.getOrderNumber(orderNumber);
        if(getOrder.getOrdernumber().equals(orderNumber)) {
            System.out.println("进来啦1");
            if (redisTemplate.opsForValue().get(orderNumber) != null && !redisTemplate.opsForValue().get(orderNumber).equals("")) {
                System.out.println("进来啦2");
                String URL = "https://openapi.alipay.com/gateway.do";
                String APP_ID = "2019022063283203";
                String APP_PRIVATE_KEY = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC/KTaH2KSLJyWF9wXl8pmbNV92q7jGQw0HqkA19LYXl4tCg9gGTE5AWa1w+BmQT/N96QO20Mli2zyh03YlwNgg0eUkk7caC6DcWK4vg9FS7y/xTzMzXXjeUyA3qoeDx2G7ou7RYPM1gP6I2FoBgSuQwRswIkyXWzbKIt71UIM4N8hYfnMJ6/K7ImiapLJh58jWCeHcjkKnSmVtp90FFqMB9grUYqwVEmurhg/33WwTgO9aEpoIMo7kgROOJpecPnKhtnaQoHLcjw0S87as25brw94ojOMYiDg/NQ+hpmwZjPbbiMUEVAnpkDysz4uHx6MrSYcIcCxqcTzlwQfRbWkPAgMBAAECggEAFcD45aivwO4phP9BepOLC3CddoHAOz+yIecr+3fnqPOj82PRl5XjactKw4pYTmXqza9QruM/p7JPShMoZM93SPTZ4Lm2oo4kNi8ZU2rqzUdO62UZ7IR8lsBa8DrFxSdRZer6xnUD+Fi/no8QXw92B7kSAP5GPQsyRvqE6OHKrQDpj5QYJDoGd4MpCC6dQ8rGrHmZ1N4EkwJAsPqCsFn1jYfZbMpd2ZmC/3MRiQka+UbQyYDQeilSEH5oMKQLfxQLMO8IVnscE9b0207SctK1M15L54fmpvPtQzMNTZseeh777p33najAKT/fzHr0Yvoxxf0cgAvWIj947qiapLce4QKBgQDxUKw6hex89uDr7yXUUt7lzz/txPcq15UICAXxyyyBcN32f+alW2DndtCi4TPkYol+YruPT3qK/UtJR4Urk0UP+wtcbjDWsfw/PTFrcFZ00rKOmEAQrHYNnY6Y9xNn5/qGAzRm5lE91HqVKPodrw2oUKhY7onF8tXAlvfm6lc/dwKBgQDKyzbN47Ea9QLKMxf6d2IMcuerPLxSMr5eUNvNm6bJpGfRt2r6k0VNQIOwXPBgrzBZ0d7EC8spQXhbti44ghcrslTVKCcp94e6MRNyp4Hn4RDJW07gDe4vmrSoNbcxUtFSyh9K1s6g5ptINw5PpHaJ6qnhykDOvs/k/wdrRnN5KQKBgDjBlqB1GzgRALm9F5KmoxI9+nU73D5RUhX/fRZviNow56OwVVkS8um9wjhs6z2OB3SYWDDOqq3CAVEM5z9mddnaW8Ozjv0QA5oEFHmGhG8ZlzF+kaLaTTHKmt1TT1ci8oNOgaaqCPWX4fTvHFSa9YVe4xl3kSPjh26ykz/WYgrlAoGALCATiLEmdCsjtENx0Dnxx6uo5QWOJISOD4+ghBh+LhnrzSIP0P4CclC7VsCiPSdhaenUguveBNgODEaTwA/uYr+m3cqi2urVSZosFSKFjaLXODj57J6bWRhcfs1RUxYmHdGFBY+/3hrPZuMz5fhvIotA87RCbbnvGnCzeJAXyCECgYAfd+sN6nE3PyISctaXSku5iSZKAh9ySy1+Ex6dl2upivniXbXLu3v0ZJfgn/PtEydF4H2rvLj+z9vbvfU/jS6wDc/Was2F2bJzs3Jvobg+Qs2Bn2mo1OpZ9UN74sjvDsWCTX3bOsMY5wSdGBFvmcaz2T5CntjNxXk4UCzsNtoA6w==";
                String FORMAT = "json";
                String CHARSET = "UTF-8";
                String ALIPAY_PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAj6uBsH/Ye6ADyKbyEiHIpLf0v0HiYL7ZUnwygcnqOaUR6+ifuQpzbMlZi6Uu+V5Qp6GbmlX3Q0sqeENHtA0C2TenMnYaqmA3UhUQ/vKoy5AO2xVSuxxzDoMYCAQmdm5HDdKw1lbygy0jIFTBJaMNld2UUlGJnHcxw+S1fJEJVKk8NDMV/UP61Cm/q2ix1ehcKtFqNJy+XuuXaAStzSRRvpQwhMPyRsd1uCESVJszETM6Hwk8L73xYHI9MUMwBYBvBXscTV2gNQQG0myn9AsVA1EpXFk9ykKopWtEI7XfP+adeROULIxarcyQq1FFcx6QVJLUqrIkGKYzt2efTsySfwIDAQAB";
                String SIGN_TYPE = "RSA2";
                AlipayClient alipayClient = new DefaultAlipayClient(URL, APP_ID, APP_PRIVATE_KEY, FORMAT, CHARSET, ALIPAY_PUBLIC_KEY, SIGN_TYPE);
                AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();//创建API对应的request
                alipayRequest.setReturnUrl("http://www.baidu.com");
                alipayRequest.setNotifyUrl("http://www.baidu.com");//在公共参数中设置回跳和通知地址
                alipayRequest.setBizContent("{" +
                        "    \"out_trade_no\":" + orderNumber + "," +
                        "    \"product_code\":\"FAST_INSTANT_TRADE_PAY\"," +
                        "    \"total_amount\":" +getOrder.getTotalprice() + "," +
                        "    \"subject\":\"每日优鲜商品\"," +
                        "    \"body\":\"每日优鲜商品\"," +
                        "    \"passback_params\":\"merchantBizType%3d3C%26merchantBizNo%3d2016010101111\"," +
                        "    \"extend_params\":{" +
                        "    \"sys_service_provider_id\":\"2088511833207846\"" +
                        "    }" +
                        "  }");//填充业务参数
                String form = "";
                try {
                    form = alipayClient.pageExecute(alipayRequest).getBody(); //调用SDK生成表单
                } catch (AlipayApiException e) {
                    e.printStackTrace();
                }
                orderFormService.updateOrderStatuId(getOrder.getOrderid());
                return JSON.toJSONString(form);
            } else {
                orderFormService.updateCancelled(getOrder.getOrderid());
                return JSON.toJSONString("订单失效");
            }
        }
        return JSON.toJSONString("订单错误");
    }
    @ApiOperation(value = "管理员点击发货，将订单状态换为配送中，正常返回1，异常返回0",notes = "切换状态，配送中")
    @ApiImplicitParam(name = "orderId", value = "订单id")
    @RequestMapping(value = "/DeliverGoods",method = RequestMethod.POST)
    private String deliverGoods(int orderId){
       try {
           int i= orderFormService.updateOrderStatuDeliverGoods(orderId);
           return JSON.toJSONString(i);
       }catch (Exception e){
            return JSON.toJSONString(0);
       }
    }
    @ApiOperation(value = "用户点退款售后切换状态", notes = "退款售后")
    @ApiImplicitParam(name = "orderId", value = "订单id")
    @RequestMapping(value = "/AfterSale",method = RequestMethod.POST)
    private String afterSale(int orderId){
        try {
            int i= orderFormService.updateOrderStatuAfterSale(orderId);
            System.out.println(i);
            return JSON.toJSONString(i);
        }catch (Exception e){
            return JSON.toJSONString(0);
        }
    }
    @ApiOperation(value = "根据用户id查询订单",notes = "根据用户展示订单")
    @ApiImplicitParam(name = "userId",value = "用户id")
    @RequestMapping(value = "/getOrderUser",method = RequestMethod.POST)
    private String getOrderUser(int userId){
       try {
           List<GetOrderSelId> getAllOrderUserId=orderFormService.getOrderUserId(userId);

           return JSON.toJSONString(getAllOrderUserId);

       }catch (Exception s){
           return JSON.toJSONString("服务器错误，查询失败");
       }
    }
    @ApiOperation(value = "根据仓库查询订单",notes = "根据仓库查询订单")
    @ApiImplicitParam(name = "wareId",value = "仓库Id")
    @RequestMapping(value = "/getOrderWare",method = RequestMethod.POST)
    private String getOrderWar(int wareId){
     try {
         List<GetOrderSelId> getAllOrderWareId=  orderFormService.getOrderWareId(wareId);

         return JSON.toJSONString(getAllOrderWareId);
     }catch (Exception s){
         return JSON.toJSONString("服务器错误，查询失败");
     }
    }
    @ApiOperation(value = "查询全部订单",notes = "查询全部订单")
    @RequestMapping(value = "/getOrderFormAll",method = RequestMethod.POST)
    private  String getOrderFormAll(){
       List<GetOrderSelId> getOrderFormAll=orderFormService.getOrderFormAll();
//        for (GetOrderSelId g: getOrderFormAll
//             ) {
//            System.out.println(g.getUserName());
//            System.out.println(g.getOrderNumber());
//        }
        return JSON.toJSONString(getOrderFormAll);
    }
    @RequestMapping("/orderDo")
    private String orderDo(Model model){

        List<GetOrderSelId> list=orderFormService.getOrderFormAll();
        for (GetOrderSelId s: list
             ) {
            System.out.println(s.getOrderNumber());
        }
      model.addAttribute("list",list);

        return "order";
    }
    @RequestMapping("/updateOrderStatus")
    private String updateOrderStatus(int orderStatusId,String ordernumber){

        int i=orderFormService.updateOrderStatus(orderStatusId,ordernumber);
        if(i==1){
            return "redirect:/getOrderForm/orderDo";
        }else {
            return "updateOrder";
        }
    }
    @RequestMapping("/updateOrderStatusDo")
    private String updateOrderStatusDo(String ordernumber,Model model){
        GetOrderSelId getOrder= orderFormService.getOrder(ordernumber);
        System.out.println(getOrder.getOrderNumber());
        model.addAttribute("form",getOrder);
        return "updateOrder";
    }
    @ApiOperation(value = "按订单编号查询订单",notes = "按订单编号查询订单")
    @RequestMapping(value = "/getOrder",method = RequestMethod.POST)
    private String getOrder(String order){
        try{
            GetOrderSelId getOrder= orderFormService.getOrder(order);

            System.out.println(getOrder.getUserName());

            return JSON.toJSONString(getOrder);
        }catch (Exception s){
            return JSON.toJSONString("服务器异常");
        }
    }
    private ExecutorService executorService = Executors.newFixedThreadPool(20);

    /**
     * <pre>
     * 第一步:验证签名,签名通过后进行第二步
     * 第二步:按一下步骤进行验证
     * 1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号，
     * 2、判断total_amount是否确实为该订单的实际金额（即商户订单创建时的金额），
     * 3、校验通知中的seller_id（或者seller_email) 是否为out_trade_no这笔单据的对应的操作方（有的时候，一个商户可能有多个seller_id/seller_email），
     * 4、验证app_id是否为该商户本身。上述1、2、3、4有任何一个验证不通过，则表明本次通知是异常通知，务必忽略。
     * 在上述验证通过后商户必须根据支付宝不同类型的业务通知，正确的进行不同的业务处理，并且过滤重复的通知结果数据。
     * 在支付宝的业务通知中，只有交易通知状态为TRADE_SUCCESS或TRADE_FINISHED时，支付宝才会认定为买家付款成功。
     * </pre>
     *
     * @param
     * @return
     */
    @ApiOperation(value = "异步支付结果，未完成",notes = "异步支付结果，未完成")
    @RequestMapping(value = "/alipay_callback",method = RequestMethod.POST)
    public String callback(HttpServletRequest request) {
        Map<String, String> params = convertRequestParamsToMap(request); // 将异步通知中收到的待验证所有参数都存放到map中
        String paramsJson = JSON.toJSONString(params);

        try {

            // 调用SDK验证签名
            boolean signVerified = AlipaySignature.rsaCheckV1(params, "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAj6uBsH/Ye6ADyKbyEiHIpLf0v0HiYL7ZUnwygcnqOaUR6+ifuQpzbMlZi6Uu+V5Qp6GbmlX3Q0sqeENHtA0C2TenMnYaqmA3UhUQ/vKoy5AO2xVSuxxzDoMYCAQmdm5HDdKw1lbygy0jIFTBJaMNld2UUlGJnHcxw+S1fJEJVKk8NDMV/UP61Cm/q2ix1ehcKtFqNJy+XuuXaAStzSRRvpQwhMPyRsd1uCESVJszETM6Hwk8L73xYHI9MUMwBYBvBXscTV2gNQQG0myn9AsVA1EpXFk9ykKopWtEI7XfP+adeROULIxarcyQq1FFcx6QVJLUqrIkGKYzt2efTsySfwIDAQAB",
                    "UTF-8", "RSA2");
            if (signVerified) {

                // 按照支付结果异步通知中的描述，对支付结果中的业务内容进行1\2\3\4二次校验，校验成功后在response中返回success，校验失败返回failure
               this.check(params);

                // 另起线程处理业务

                // 如果签名验证正确，立即返回success，后续业务另起线程单独处理
                // 业务处理失败，可查看日志进行补偿，跟支付宝已经没多大关系。
                return "success";
            } else {
                System.out.println("支付宝回调签名认证失败，signVerified=false, paramsJson:{}");
                return "failure";
            }
        } catch (AlipayApiException e) {
            System.out.println("支付宝回调签名认证失败,paramsJson:{},errorMsg:{}");
            return "failure";
        }
    }

    // 将request中的参数转换成Map
    private static Map<String, String> convertRequestParamsToMap(HttpServletRequest request) {
        Map<String, String> retMap = new HashMap<String, String>();

        Set<Map.Entry<String, String[]>> entrySet = request.getParameterMap().entrySet();

        for (Map.Entry<String, String[]> entry : entrySet) {
            String name = entry.getKey();
            String[] values = entry.getValue();
            int valLen = values.length;

            if (valLen == 1) {
                retMap.put(name, values[0]);
            } else if (valLen > 1) {
                StringBuilder sb = new StringBuilder();
                for (String val : values) {
                    sb.append(",").append(val);
                }
                retMap.put(name, sb.toString().substring(1));
            } else {
                retMap.put(name, "");
            }
        }

        return retMap;
    }

    private String buildAlipayNotifyParam(Map<String, String> params) {
        String json = JSON.toJSONString(params);
        System.out.println("params:"+params);
        return json;
    }
    /**
     * 1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号，
     * 2、判断total_amount是否确实为该订单的实际金额（即商户订单创建时的金额），
     * 3、校验通知中的seller_id（或者seller_email)是否为out_trade_no这笔单据的对应的操作方（有的时候，一个商户可能有多个seller_id/seller_email），
     * 4、验证app_id是否为该商户本身。上述1、2、3、4有任何一个验证不通过，则表明本次通知是异常通知，务必忽略。
     * 在上述验证通过后商户必须根据支付宝不同类型的业务通知，正确的进行不同的业务处理，并且过滤重复的通知结果数据。
     * 在支付宝的业务通知中，只有交易通知状态为TRADE_SUCCESS或TRADE_FINISHED时，支付宝才会认定为买家付款成功。
     *
     * @param params
     * @throws AlipayApiException
     */
    private void check(Map<String, String> params) throws AlipayApiException {
        String outTradeNo = params.get("out_trade_no");

        // 1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号，
        OrderForm getOrder= orderFormService.getOrderNumber(outTradeNo); // 这个方法自己实现
        if (getOrder == null) {
            throw new AlipayApiException("out_trade_no错误");
        }

        // 2、判断total_amount是否确实为该订单的实际金额（即商户订单创建时的金额），
        long total_amount = new BigDecimal(params.get("total_amount")).multiply(new BigDecimal(100)).longValue();
        if (total_amount != getOrder.getTotalprice().longValue()) {
            throw new AlipayApiException("error total_amount");
        }

        // 3、校验通知中的seller_id（或者seller_email)是否为out_trade_no这笔单据的对应的操作方（有的时候，一个商户可能有多个seller_id/seller_email），
        // 第三步可根据实际情况省略

        // 4、验证app_id是否为该商户本身。
        if (!params.get("app_id").equals("2019022063283203")) {
            throw new AlipayApiException("app_id不一致");
        }
    }

}
